<template>
  <!-- <div class="fg-style"> -->
  <a-form
    ref="generateForm"
    :model="model"
    :rules="rules"
    layout="vertical"
    :label-align="widgetForm.config.labelAlign"
    :label-col="widgetForm.config.labelCol"
    :hide-required-mark="widgetForm.config.hideRequiredMark"
  >
    <template v-for="(parentItem, index) of showList" :key="parentItem.key">
      <lineCutApart v-if="noBorder && parentItem.list.some((item) => item.options.visibleFlag) && index !== 0" />
      <!-- && parentItem.textInfo.type === 'text' -->
      <a-card
        v-if="parentItem.list.some((item) => item.options.visibleFlag)"
        :class="[{ 'margin-b-sm2': !noBorder }]"
        :bordered="noBorder ? false : !!parentItem.textInfo"
        :body-style="
          parentItem.textInfo && parentItem.textInfo.expandFlag
            ? {
                padding: 0,
                height: 0,
                overflow: 'hidden'
              }
            : noBorder
            ? {
                padding: 0,
                height: 'auto'
              }
            : {
                padding: '16px',
                height: 'auto',
                paddingRight: parentItem.textInfo && hasFixedField(parentItem.list) ? '64px' : '16px'
              }
        "
        :head-style="
          noBorder
            ? {
                'border-bottom': 'none',
                paddingLeft: 0,
                paddingBottom: '10px'
              }
            : {}
        "
      >
        <template v-if="parentItem.textInfo && parentItem.textInfo.type === 'text'" #title>
          <span v-if="!parentItem.textInfo.options.showLabel">{{ parentItem.textInfo.fieldName }}</span>
          <a-tooltip v-if="parentItem.textInfo.options.hidePromptFlag">
            <template #title>{{ parentItem.textInfo.options.promptInfo }}</template>
            <i
              class="wentishuoming icpIconfont hover-primary cursor-pointer"
              style="font-size: 20px; line-height: normal"
            ></i>
          </a-tooltip>
          <span
            v-if="!parentItem.textInfo.options.hidePromptFlag && parentItem.textInfo.options.promptInfo"
            class="filed-desc"
            >{{ parentItem.textInfo.options.promptInfo }}</span
          >
          <!-- <a-divider v-if="parentItem.textInfo.options.showDivider" style="margin: 0" /> -->
        </template>
        <template v-if="parentItem.textInfo && parentItem.textInfo.type === 'text'" #extra>
          <span class="hover-primary cursor-pointer" @click="expand(parentItem)">
            {{ parentItem.textInfo.expandFlag ? '展开' : '收起' }}
            <i v-if="!parentItem.textInfo.expandFlag" class="icpIconfont biaoqianshouqi"></i>
            <i v-else class="icpIconfont biaoqianzhankai"></i>
          </span>
        </template>
        <a-row :gutter="16">
          <template v-for="element of parentItem.list" :key="element.key">
            <a-col v-if="element.options.visibleFlag" :span="element.options.gridLayoutNumber">
              <template v-if="element.type === 'grid'">
                <div v-for="(item, i) in element.columns" :key="i" style="display: flex; align-items: center">
                  <a-row
                    v-if="element.key"
                    :key="element.key"
                    style="flex: 1"
                    type="flex"
                    :gutter="element.options.gutter ?? 0"
                    :justify="element.options.justify"
                    :align="element.options.align"
                  >
                    <a-col v-for="(col, colIndex) of item" :key="colIndex" :span="col.gridLayoutNumber ?? 0">
                      <template v-for="colItem of col.list" :key="colItem.key">
                        <AntdGenerateFormItem
                          v-if="colItem.options.visibleFlag"
                          :model="model"
                          :element="colItem"
                          :config="data.config"
                          :disabled="disabled || disabledFieldCodes.includes(colItem.fieldCode)"
                          :remote-replace="remoteReplace"
                          @change="(val) => itemOptionChange(val, i)"
                        />
                      </template>
                    </a-col>
                  </a-row>
                  <div class="btn-group">
                    <Icon size="24" @click="add(element, i)">
                      <AddCircle color="#0177fd" />
                    </Icon>
                    <Icon size="24" @click="reduce(element, i)">
                      <RemoveCircle color="#0177fd" />
                    </Icon>
                  </div>
                </div>
              </template>
              <template v-else-if="element.type === 'fixedCombination'">
                <GenerateFixedCombination
                  :model="model"
                  :approval-permission="approvalPermission"
                  :element="element"
                  :config="data.config"
                  :disabled="disabled"
                  :disabled-field-codes="disabledFieldCodes"
                  :remote-replace="remoteReplace"
                />
              </template>
              <template v-else-if="element.type === 'packing'">
                <PackingCom
                  :model="model"
                  :approval-permission="approvalPermission"
                  :element="element"
                  :config="data.config"
                  :disabled="disabled || disabledFieldCodes.includes(element.fieldCode)"
                  :remote-replace="remoteReplace"
                />
              </template>
              <AntdGenerateFormItem
                v-else
                :key="element.key"
                :model="model"
                :element="element"
                :config="data.config"
                :is-show="disabled"
                :disabled="disabled || disabledFieldCodes.includes(element.fieldCode)"
                :remote-replace="remoteReplace"
                @change="itemOptionChange"
              />
            </a-col>
          </template>
        </a-row>
      </a-card>
    </template>
  </a-form>
  <!-- </div> -->
</template>

<script lang="ts">
import { defineComponent, onMounted, reactive, toRefs, watch } from 'vue'
import { message } from 'ant-design-vue'
import AntdGenerateFormItem from './AntdGenerateFormItem.vue'
import { antd, getDatePickerFormat, convertFieldValueToShow, getValueByModel } from './config'
import { fixedCombinationCode } from './config/enum'
import { fieldType } from './config/enum'
import { v4 } from 'uuid'
import { RemoveCircle, AddCircle } from '@vicons/ionicons5'
// import { randomRange } from '@/utils/index'
import { cloneDeep } from 'lodash-es'
import type { Rule } from 'ant-design-vue/es/form'
import GenerateFixedCombination from './GenerateFixedCombination.vue'
import PackingCom from './packing/index.vue'
import { scrollToFirstError } from '@@/utils/index'
// TODO: 用setup语法糖模式重写一下吧
export default defineComponent({
  name: 'AntdGenerateForm',
  components: {
    AntdGenerateFormItem,
    GenerateFixedCombination,
    RemoveCircle,
    AddCircle,
    PackingCom
  },
  props: {
    data: {
      type: Object,
      default: antd.widgetForm
    },
    isShow: {
      type: Boolean,
      default: false
    },
    disabled: {
      type: Boolean,
      default: false
    },
    remoteReplace: {
      type: Object,
      required: true
    },
    disabledFieldCodes: {
      type: Array,
      default: () => []
    },
    queryValueFlag: {
      // 是否查询字段的值
      type: Boolean,
      default: false
    },
    presetValues: {
      // 表单预置值
      type: Object,
      required: false,
      default: () => ({})
    },
    approvalPermission: {
      // 审批状态
      type: Boolean,
      default: false
    },
    noBorder: {
      // card是否不使用border（适用于任务弹窗内部，不带border和padding的）,默认为false
      // 该项为true时，card没有border、padding、marginbottom。分割方式使用 lineCutApart
      type: Boolean,
      default: false
    },
    defaultRetract: {
      type: Boolean,
      default: false
    }
  },
  emits: ['change'],
  setup(props, context) {
    const state = reactive({
      showList: [] as any, // 用于添加card
      generateForm: null as any,
      model: {} as any,
      rules: {} as any,
      widgetForm: (props.data && cloneDeep(props.data)) ?? antd.widgetForm
      // expandFlag: props.defaultRetract
    })
    let defaultWidgetForm: any = null

    // 下拉框的联动事件
    const itemOptionChange = (data, index) => {
      const { element, value } = data
      if (!defaultWidgetForm) {
        defaultWidgetForm = cloneDeep(state.widgetForm)
      }
      if (element.options.linkContent && element.options.linkContent.length) {
        element.options.linkContent.forEach((el) => {
          const tempValue = typeof value === 'number' ? String(value) : value
          if (tempValue.includes(el.optionVal)) {
            el.linkedFields.forEach((fieldModelItem) => {
              if (element.parentKey) {
                // parentKey为循环事件的id，如果存在，则只需要控制当前行的其他子组件即可
                const gridItem = state.widgetForm.list.find((e) => e.key === element.parentKey)
                const item = gridItem.columns[index].find((e) => e.list[0].defaultKey === fieldModelItem.linkFrontId)
                if (item) {
                  item.list[0].options.visibleFlag = fieldModelItem.visibleFlag
                }
              } else {
                // parentKey不存在就直接控制表单内的第一层组件
                const item = state.widgetForm.list.find((e) => e.key === fieldModelItem.linkFrontId)
                if (item) {
                  item.options.visibleFlag = fieldModelItem.visibleFlag
                }
              }
            })
          } else if (Array.isArray(tempValue)) {
            // 复选框
            el.linkedFields.forEach((fieldModelItem) => {
              const item = state.widgetForm.list.find((e) => e.key === fieldModelItem.linkFrontId)
              const defaultItem = defaultWidgetForm.list.find((e) => e.key === fieldModelItem.linkFrontId)
              console.log('defaultItem', defaultWidgetForm)
              if (item) {
                item.options.visibleFlag = defaultItem.options.visibleFlag
              }
            })
          }
        })
      }
      if (element.options.attr === 1) {
        // 字段属性为业务字段，通知父组件发生变化
        const val = {}
        val[element.fieldCode] = value
        context.emit('change', val)
      }
    }

    /**
     * 获取字段值
     */
    const getFieldValue = (field) => {
      return props.queryValueFlag ? field.options.valueContextObj : field.options.defaultVal
    }

    const generateModel = (list: any[]) => {
      for (let index = 0; index < list.length; index++) {
        const model = list[index].model
        if (!model) {
          return
        }
        setFieldValue(list[index], model)
        setFieldRules(list[index], model)
        // setLinkedFieldVisiable(list[index])
        setValByWatchPresetValues()
      }
    }

    /**
     * 设置字段值
     */
    const setFieldValue = (field, model) => {
      if (field.type === 'grid') {
        field.columns[0].forEach((col: any) => generateModel(col.list))
      }
      //  else if (field.type === 'text') {
      //   // 说明文字不作处理
      // }
      else {
        state.model[model] = convertModelToShow(field)
      }
    }

    /**
     * 转换值格式
     */
    const convertModelToShow = (field) => {
      const fieldValue = getFieldValue(field)
      const fieldObj = {
        fieldType: field.fieldType,
        valueContextObj: fieldValue,
        multipleFlag: field.options.multipleFlag
      }
      return convertFieldValueToShow(fieldObj)
    }

    /**
     * 设置字段的校验规则
     */
    const setFieldRules = (field, model) => {
      if (
        field.fieldType === fieldType.text ||
        field.fieldType === fieldType.cycleEvent ||
        field.fieldType === fieldType.fixedCombination
      ) {
        return
      }
      const required = field.options.rules.required ? true : false
      if (field.fieldType === fieldType.singleLineText) {
        const rules = [{ required: required, validator: checkInput, trigger: 'blur' }]
        state.rules[model] = rules
        return
      }
      if (field.fieldType === fieldType.multiLineText) {
        const rules = [{ required: required, validator: checkTextarea, trigger: 'blur' }]
        state.rules[model] = rules
        return
      }
      if (field.fieldType === fieldType.number) {
        const rules = [{ required: required, validator: checkNumber, trigger: 'blur', type: 'number' }]
        state.rules[model] = rules
        return
      }
      if (field.fieldType === fieldType.radio) {
        const rules = [{ required: required, validator: checkRadio, trigger: 'change' }]
        state.rules[model] = rules
        return
      }
      if (field.fieldType === fieldType.checkbox) {
        const rules = [{ required: required, validator: checkCheckbox, trigger: 'change' }]
        state.rules[model] = rules
        return
      }
      if (field.fieldType === fieldType.select) {
        const rules = [{ required: required, validator: checkSelect, trigger: 'change' }]
        state.rules[model] = rules
        return
      }
      if (field.fieldType === fieldType.cascader) {
        const rules = [{ required: required, validator: checkCascader, trigger: 'change' }]
        state.rules[model] = rules
        return
      }
      if (field.fieldType === fieldType.treeSelect) {
        const rules = [{ required: required, validator: checkTreeSelect, trigger: 'change' }]
        state.rules[model] = rules
        return
      }
      if (field.fieldType === fieldType.dateTime) {
        const rules = [{ required: required, validator: checkDateTime, trigger: 'change' }]
        state.rules[model] = rules
        return
      }
      if (field.fieldType === fieldType.upload) {
        const rules = [{ required: required, validator: checkUpload, trigger: 'change' }]
        state.rules[model] = rules
      }
      if (field.fieldType === fieldType.packing) {
        const rules = [{ required: required, validator: validatePacking, trigger: 'change' }]
        state.rules[model] = rules
      }
    }

    /**
     * 设置被联动字段的显示隐藏
     */
    const setLinkedFieldVisiable = (data) => {
      const value = getValueByModel(state.model[data.model], data)
      if (value === undefined || value === null || value === '') {
        return
      }
      if ('radio' === data.type) {
        itemOptionChange({ element: data, value }, 0)
      }
      if ('select' === data.type && 1 === data.options.remote) {
        // 固定选项的下拉框
        for (const val of value) {
          itemOptionChange({ element: data, value: val }, 0)
        }
      }
    }

    // 获取组件选项（下拉，单选，多选）
    const generateOptions = (list: any[]) => {
      list.forEach((item) => {
        if (item.type === 'grid') {
          item.columns[0].forEach((col: any) => generateOptions(col.list))
        } else if (item.options.remote === 2) {
        }
      })
    }

    watch(
      () => props.isShow,
      (val) => {
        if (!val) {
          return
        }
        state.widgetForm = (props.data && cloneDeep(props.data)) ?? antd.widgetForm
        state.model = {}
        state.rules = {}
        state.showList = []
        generateModel(state.widgetForm.list)
        generateOptions(state.widgetForm.list)
        state.widgetForm.list.forEach((item) => {
          if (item.type === 'text') {
            state.showList.push({
              list: [],
              key: Math.random(),
              textInfo: item,
              expandFlag: props.defaultRetract
            })
          } else {
            const listLength = state.showList.length
            if (listLength) {
              state.showList[state.showList.length - 1].list.push(item)
            } else {
              state.showList.push({
                list: [item],
                key: Math.random()
              })
            }
          }
        })
      },
      { deep: true, immediate: true }
    )

    /**
     * 设置值（通过监听表单预设值）
     */
    const setValByWatchPresetValues = () => {
      if (!props.presetValues || !state.widgetForm.list) {
        return
      }
      for (const item of state.widgetForm.list) {
        if (item.options.attr !== 1) {
          continue
        }
        if (item.fieldCode in props.presetValues) {
          if (item.fieldCode in fixedCombinationCode) {
            state.model[item.model] = cloneDeep(props.presetValues[item.fieldCode])
          } else {
            state.model[item.model] = state.model[item.model] || cloneDeep(props.presetValues[item.fieldCode])
          }
        }
        setLinkedFieldVisiable(item)
      }
    }

    watch(
      () => props.presetValues,
      () => {
        setValByWatchPresetValues()
      },
      { deep: true, immediate: true }
    )

    onMounted(() => {
      generateModel(state.widgetForm?.list ?? [])
      generateOptions(state.widgetForm?.list ?? [])
    })

    /**
     * 获取表单填写数据
     */
    const getData = (isValidate = true) => {
      return new Promise((resolve, reject) => {
        if (isValidate) {
          state.generateForm
            .validate()
            .then((validate: boolean) => {
              if (validate) {
                resolve(convertSubmitData())
              } else {
                message.error('验证失败')
              }
            })
            .catch((error: Error) => {
              reject(error)
              scrollToFirstError()
            })
        } else {
          resolve(convertSubmitData())
        }
      })
    }

    // 转换提交数据格式
    const convertSubmitData = () => {
      const data: any[] = []
      for (const key in state.model) {
        const field = getFieldByFieldId(key)
        if (!field) {
          continue
        }
        const tempItem: any = {
          fieldId: key,
          visibleFlag: field.options.visibleFlag,
          fieldCode: field.fieldCode
        }
        if (field.type !== 'text') {
          const value = getValueByModel(state.model[key], field)
          tempItem.valueContextObj = convertValueToSubmit(field, value)
        }
        data.push(tempItem)
      }
      return data
    }

    /**
     * 获取表单填写数据
     */
    const getFormFieldValues = (isValidate = true) => {
      return new Promise((resolve, reject) => {
        if (isValidate) {
          state.generateForm
            .validate()
            .then((validate: boolean) => {
              if (validate) {
                resolve(converFormFieldValuesToObj())
              } else {
                message.error('验证失败')
              }
            })
            .catch((error: Error) => {
              reject(error)
            })
        } else {
          resolve(converFormFieldValuesToObj())
        }
      })
    }

    // 转换表单数据格式
    const converFormFieldValuesToObj = () => {
      const data = {}
      for (const field of state.widgetForm.list) {
        if (field.key && field.model) {
          data[field.model] = getValueByModel(state.model[field.model], field)
        }
      }
      return data
    }

    /**
     * 转换默认值格式
     */
    const convertValueToSubmit = (localField, value) => {
      if ([fieldType.singleLineText, fieldType.multiLineText, fieldType.dateTime].includes(localField.fieldType)) {
        return { stringVal: value }
      } else if (localField.fieldType === fieldType.number) {
        if (value === undefined || value === null || value === '') {
          return { stringVal: null }
        }
        return { stringVal: value }
      } else if (localField.fieldType === fieldType.radio) {
        return convertRadioToSubmit(localField, value)
      } else if (localField.fieldType === fieldType.checkbox) {
        return convertCheckboxToSubmit(localField, value)
      } else if (localField.fieldType === fieldType.select) {
        return convertSelectToSubmit(localField, value)
      } else if (localField.fieldType === fieldType.upload) {
        return convertUploadToSubmit(value)
      } else if (localField.fieldType === fieldType.cascader) {
        return convertCascaderToSubmit(value)
      } else if (localField.fieldType === fieldType.treeSelect) {
        return convertTreeSelectToSubmit(localField, value)
      } else if (localField.fieldType === fieldType.fixedCombination) {
        return { comboVal: value }
      } else if (localField.fieldType === fieldType.packing) {
        return { packageSpecVal: value }
      }
      return null
    }

    /**
     * 转换单选的值
     */
    const convertRadioToSubmit = (localField, value) => {
      if (value) {
        const option = localField.options.options.find((opt) => opt.value === value)
        if (option) {
          return { optionVal: { value: option.value, label: option.label } }
        }
      }
      return { optionVal: null }
    }

    /**
     * 转换多选的值
     */
    const convertCheckboxToSubmit = (localField, value) => {
      if (!value) {
        return { optionsVal: null }
      }
      const tempArr: any = []
      for (const optVal of value) {
        const option = localField.options.options.find((opt) => opt.value === optVal)
        if (option) {
          tempArr.push({ value: option.value, label: option.label })
        }
      }
      if (tempArr.length > 0) {
        return { optionsVal: tempArr }
      }
      return { optionsVal: null }
    }

    /**
     * 转换下拉选择的值
     */
    const convertSelectToSubmit = (localField, value) => {
      if (!value) {
        return { optionsVal: null }
      }
      const optionArr = localField.options.remote === 1 ? localField.options.options : localField.options.remoteOptions
      const valueArr = localField.options.multipleFlag ? value : [value]
      const tempArr: any = []
      for (const optVal of valueArr) {
        const option = optionArr.find((opt) => opt.value === optVal)
        if (option) {
          tempArr.push({ value: option.value, label: option.label, fullLabel: option.fullLabel })
        }
      }
      if (tempArr.length > 0) {
        return { optionsVal: tempArr }
      }
      return { optionsVal: null }
    }

    /**
     * 转换文件上传的值
     */
    const convertUploadToSubmit = (value) => {
      if (value) {
        const fileArr = value.map((item) => {
          return {
            fileId: item.uid,
            fileName: item.name,
            fileSize: item.size
          }
        })
        if (fileArr.length > 0) {
          return { fileUploadVal: fileArr }
        }
      }
      return { fileUploadVal: null }
    }

    /**
     * 转换级联的值
     */
    const convertCascaderToSubmit = (value) => {
      if (!value) {
        return { optionsVal: null }
      }
      const tempArr: any = []
      for (const optVal of value) {
        tempArr.push({ value: optVal })
      }
      if (tempArr.length > 0) {
        return { optionsVal: tempArr }
      }
      return { optionsVal: null }
    }

    /**
     * 转换树选择的值
     */

    // 获取当前选中的fullLbel如果需要传
    const getFeeTypeConfigName = (id, arr, fieldNames) => {
      let fullLabel = ''
      let label = ''
      arr = arr || []
      arr.some((item) => {
        if (item[fieldNames.value] === id) {
          fullLabel = item[fieldNames.fullLabel]
          label = item[fieldNames.label]
          return true
        }
        if (Array.isArray(item[fieldNames.children]) && item[fieldNames.children].length > 0) {
          fullLabel = getFeeTypeConfigName(id, item[fieldNames.children], fieldNames).fullLabel
          label = getFeeTypeConfigName(id, item[fieldNames.children], fieldNames).label
          if (fullLabel) {
            return true
          }
        }
        return false
      })
      return { fullLabel, label }
    }
    const convertTreeSelectToSubmit = (localField, value) => {
      if (!value) {
        return { optionsVal: null }
      }
      const optionArr = localField.options.remote === 1 ? localField.options.options : localField.options.remoteOptions
      const fieldNames = {
        children: localField.options.remoteConfig.children,
        fullLabel: localField.options.remoteConfig.fullLabel,
        label: localField.options.remoteConfig.labelKey,
        value: localField.options.remoteConfig.valueKey
      }
      const { label, fullLabel } = getFeeTypeConfigName(value, optionArr, fieldNames)
      return {
        optionsVal: [
          {
            value: value,
            label,
            fullLabel
          }
        ]
      }
    }

    /**
     * 转换业务数据
     */
    const convertBusinessData = () => {
      const businessData = {}
      for (const field of state.widgetForm.list) {
        if (field.fieldCode && field.model) {
          businessData[field.fieldCode] = getValueByModel(state.model[field.model], field)
        }
      }
      return businessData
    }

    /**
     * 获取业务数据
     */
    const getBusinessData = (isValidate = true) => {
      return new Promise((resolve, reject) => {
        if (isValidate) {
          state.generateForm
            .validate()
            .then((validate: boolean) => {
              if (validate) {
                resolve(convertBusinessData())
              } else {
                message.error('验证失败')
              }
            })
            .catch((error: Error) => {
              reject(error)
            })
        } else {
          resolve(convertBusinessData())
        }
      })
    }

    const reset = () => {
      state.generateForm.resetFields()
    }

    // 循环事件（加）
    const add = (el: any, i: number) => {
      const tempItem = cloneDeep(el)
      tempItem.columns[i].forEach((element: any) => {
        element.list.forEach((item: any) => {
          const key = v4().replaceAll('-', '')
          item.key = key
          item.model = `${key}`
        })
      })
      el.columns.splice(i + 1, 0, tempItem.columns[i])
    }
    // 循环事件（减）
    const reduce = (el: any, i: number) => {
      if (el.columns.length === 1) {
        message.error('至少保留一行')
        return
      }
      el.columns.splice(i, 1)
    }

    /**
     * 根据字段Id查询字段Obj
     */
    const getFieldByFieldId = (fieldId) => {
      return state.widgetForm.list.find((temp) => fieldId === temp.model)
    }

    /**
     * 根据校验规则查询字段Obj
     */
    const getFieldByRule = (_rule) => {
      return getFieldByFieldId(_rule.field)
    }

    /**
     * 校验输入框
     */
    const checkInput = async (_rule: Rule, value: string) => {
      const field = getFieldByRule(_rule) || { options: {} }
      if (value) {
        if (value.length > field.options.maxlength) {
          return Promise.reject(field.fieldName + '内容长度限制为' + field.options.maxlength)
        }
        if (field.options.format === 2) {
          // 仅允许填写手机号和座机
          if (/^((0\d{2,3}-\d{7,8})|(1[3456789]\d{9}))$/.test(value)) {
            return Promise.resolve()
          }
          return Promise.reject('请输入正确的手机号或座机')
        } else if (field.options.format === 3) {
          // 仅允许填写邮箱
          if (/^(\w-*\.*)+@(\w-?)+(\.\w{2,})+$/.test(value)) {
            return Promise.resolve()
          }
          return Promise.reject('请输入正确的邮箱')
        }
        return Promise.resolve()
      }
      if (_rule.required) {
        // 必填
        return Promise.reject('请输入' + field.fieldName)
      }
      return Promise.resolve()
    }

    /**
     * 校验多行文本
     */
    const checkTextarea = async (_rule: Rule, value: string) => {
      const field = getFieldByRule(_rule) || { options: {} }
      if (value) {
        if (value.length > field.options.maxlength) {
          return Promise.reject(field.fieldName + '内容长度限制为' + field.options.maxlength)
        }
        return Promise.resolve()
      }
      if (_rule.required) {
        // 必填
        return Promise.reject('请输入' + field.fieldName)
      }
      return Promise.resolve()
    }

    /**
     * 校验数值
     */
    const checkNumber = async (_rule: Rule, value: number) => {
      const field = getFieldByRule(_rule) || { options: {} }
      if (value !== undefined && value !== null) {
        if (value < field.options.min) {
          return Promise.reject(field.fieldName + '最小值为' + field.options.min)
        }
        if (value > field.options.max) {
          return Promise.reject(field.fieldName + '最大值为' + field.options.max)
        }
        if (field.options.decimalPoint === 0) {
          if (Number.isInteger(value)) {
            return Promise.resolve()
          }
          return Promise.reject('必须为整数')
        } else if (field.options.decimalPoint === 1) {
          if (/^[+-]?\d+(?:\.\d{0,1})?$/.test(String(value))) {
            return Promise.resolve()
          }
          return Promise.reject('小数点后最多一位小数')
        } else if (field.options.decimalPoint === 2) {
          if (/^[+-]?\d+(?:\.\d{0,2})?$/.test(String(value))) {
            return Promise.resolve()
          }
          return Promise.reject('小数点后最多两位小数')
        }
        return Promise.resolve()
      }
      if (_rule.required) {
        // 必填
        return Promise.reject('请输入' + field.fieldName)
      }
      return Promise.resolve()
    }

    /**
     * 校验单选框
     */
    const checkRadio = async (_rule: Rule, value: string) => {
      const field = getFieldByRule(_rule) || { options: {} }
      if (_rule.required) {
        if (value) {
          return Promise.resolve()
        }
        // 必填
        return Promise.reject('请选择' + field.fieldName)
      }
      return Promise.resolve()
    }

    /**
     * 校验复选框
     */
    const checkCheckbox = async (_rule: Rule, value: []) => {
      const field = getFieldByRule(_rule) || { options: {} }
      if (_rule.required) {
        if (value && value.length > 0) {
          return Promise.resolve()
        }
        // 必填
        return Promise.reject('请选择' + field.fieldName)
      }
      return Promise.resolve()
    }

    /**
     * 校验选择框
     */
    const checkSelect = async (_rule: Rule, value: {} | []) => {
      const field = getFieldByRule(_rule) || { options: {} }
      const val = getValueByModel(value, field)
      if (_rule.required) {
        if (val && val.length > 0) {
          return Promise.resolve()
        }
        // 必填
        return Promise.reject('请选择' + field.fieldName)
      }
      return Promise.resolve()
    }

    /**
     * 校验级联
     */
    const checkCascader = async (_rule: Rule, value: string | []) => {
      const field = getFieldByRule(_rule) || { options: {} }
      if (_rule.required) {
        if (value && value.length > 0) {
          return Promise.resolve()
        }
        // 必填
        return Promise.reject('请选择' + field.fieldName)
      }
      return Promise.resolve()
    }

    /**
     * 校验树选择
     */
    const checkTreeSelect = async (_rule: Rule, value: string | []) => {
      const field = getFieldByRule(_rule) || { options: {} }
      if (_rule.required) {
        if (value) {
          return Promise.resolve()
        }
        // 必填
        return Promise.reject('请选择' + field.fieldName)
      }
      return Promise.resolve()
    }

    /**
     * 校验日期时间选择
     */
    const checkDateTime = async (_rule: Rule, value: string | []) => {
      const field = getFieldByRule(_rule) || { options: {} }
      if (_rule.required) {
        if (value && value.length > 0) {
          return Promise.resolve()
        }
        // 必填
        return Promise.reject('请选择' + field.fieldName)
      }
      return Promise.resolve()
    }

    /**
     * 校验文件上传
     */
    const checkUpload = async (_rule: Rule, value: []) => {
      const field = getFieldByRule(_rule) || { options: {} }
      if (_rule.required && (!value || value.length < 1)) {
        return Promise.reject('请上传文件')
      }
      if (field.options.attachmentNumber === 0) {
        return Promise.resolve()
      }
      if (value && value.length !== 0 && value.length !== Number(field.options.attachmentNumber)) {
        return Promise.reject('上传数量不匹配')
      }
      return Promise.resolve()
    }

    /**
     * 校验包装规格
     */
    const validatePacking = async (_rule: Rule, value: any) => {
      if (!value) {
        return Promise.reject('请填写包装规格')
      }
      if (!value.packageSpecName) {
        return Promise.reject('请填写包装规格')
      }
      if (!value.minSpecName) {
        return Promise.reject('请选择发放单位')
      }
      return Promise.resolve()
    }

    // 判断是否存在固定字段：用于判断卡片是否要添加右边距
    const hasFixedField = (list: any[]) => {
      return list.some((item) => item.fieldType === fieldType.fixedCombination)
    }

    // 切换卡片内容展开收起
    const expand = (parentItem) => {
      parentItem.textInfo.expandFlag = !parentItem.textInfo.expandFlag
    }

    return {
      ...toRefs(state),
      getData,
      reset,
      add,
      reduce,
      itemOptionChange,
      getDatePickerFormat,
      getBusinessData,
      getFormFieldValues,
      hasFixedField,
      expand
    }
  }
})
</script>
<style lang="less" scoped>
.fg-style {
  // padding: 0 60px;
}
:deep(.btn-group) {
  white-space: nowrap;
  span {
    cursor: pointer;
  }
}
</style>
